/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2022-04-30 15:35:44
 * @LastEditors: ding-cx
 * @LastEditTime: 2022-06-08 14:26:54
 * @Description: file content
 */
/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2022-04-30 15:34:18
 * @LastEditors: ding-cx
 * @LastEditTime: 2022-04-30 15:34:18
 * @Description: file content
 */

import DingTalkBasePublicService from "./BasePublicService";
import { Dingtalk } from "../dingtalk";
import { DateFormat } from "@diyaner/ding";

export default class OAService extends DingTalkBasePublicService {
	/**
	 * 查询一个审批实例的详情
	 *
	 * @param {string} access_token
	 * @param {string} id 审批实例id
	 * @memberof PlatformDingTalkBaseOAService
	 */
	async getDetail(id: string) {
		const url = `/v1.0/workflow/processInstances?processInstanceId=${id}`;

		const res = await this.nvRequest<Dingtalk.nv.response.IGetProcessInstanceDetail>(url, {
			method: "GET",
		});

		return res;
	}

	/**
	 * 获取审批实例id列表
	 * - 基础接口，根据文档传递参数
	 * - https://open.dingtalk.com/document/orgapp/obtain-an-approval-list-of-instance-ids
	 *
	 * @param {string} access_token
	 * @param {*} params 查询条件
	 * @memberof PlatformDingTalkBaseOAService
	 */
	async getInstanceIdList(params: Dingtalk.nv.request.IGetInstanceIdListParams) {
		const url = `/v1.0/workflow/processes/instanceIds/query`;
		const res = await this.nvRequest<Dingtalk.nv.response.IGetInstanceIdListParams>(url, {
			method: "POST",
			data: {
				...params,
			},
		});
		return res;
	}

	/**
	 *
	 * @return {*}
	 * @memberof PlatformDingTalkBaseOAService
	 */
	/**
	 *
	 * 获取一天的审批实例id列表，如果超过分页最大20，则递归获取
	 *
	 * @param {string} processCode 流程模板id
	 * @param {Date} date 一个日期
	 * @param {dingTalk.nv.request.IGetInstanceIdListParams["statuses"]} [statuses] 可选，只查询某个状态的
	 * @return {*}
	 * @memberof PlatformDingTalkBaseOAService
	 */
	async getInstanceIdListByOneDay(
		processCode: string,
		date: Date,
		statuses?: Dingtalk.nv.request.IGetInstanceIdListParams["statuses"]
	) {
		const df = DateFormat.init(date);
		const startTime = new Date(df.format("yyyy-MM-dd 00:00:00")).getTime();
		const endTime = new Date(df.format("yyyy-MM-dd 23:59:59")).getTime();

		const resList: string[] = [];
		const doit = async (nextToken: string | null) => {
			const params = {} as Dingtalk.nv.request.IGetInstanceIdListParams;
			params.startTime = startTime;
			params.endTime = endTime;
			params.maxResults = 20;
			params.processCode = processCode;
			statuses && (params.statuses = statuses);
			nextToken && (params.nextToken = Number(nextToken));
			const res = await this.getInstanceIdList(params);
			resList.push(...res.result.list);
			if (res.result.nextToken) {
				await doit(res.result.nextToken);
			}
		};
		await doit(null);
		return resList;
	}

	/**
	 *
	 *  获取一个用户userid的一个月的流程实例id列表
	 * - 如果超过20，将会递归调用
	 *
	 * @param {string} processCode 审批流模板id
	 * @param {string} userid 要查询的用户userid
	 * @param {Date} month 传递一个日期，将自动获取该日期所在的整个月份范围
	 * @param {dingTalk.nv.request.IGetInstanceIdListParams["statuses"]} [statuses] 状态
	 * @memberof PlatformDingTalkBaseOAService
	 */
	async getInstanceIdListByOneUserOneMonth(
		processCode: string,
		userid: string,
		month: Date,
		statuses?: Dingtalk.nv.request.IGetInstanceIdListParams["statuses"]
	) {
		const df = DateFormat.init(month);
		const montharr = df.currentMonth(true) as [string, string];
		const startTime = new Date(montharr[0] + " 00:00:00").getTime();
		const endTime = new Date(montharr[1] + " 23:59:59").getTime();

		const resList: string[] = [];
		const doit = async (nextToken: string | null) => {
			const params = {} as Dingtalk.nv.request.IGetInstanceIdListParams;
			params.startTime = startTime;
			params.endTime = endTime;
			params.maxResults = 20;
			params.processCode = processCode;
			params.userIds = [userid];
			statuses && (params.statuses = statuses);
			nextToken && (params.nextToken = Number(nextToken));
			const res = await this.getInstanceIdList(params);
			resList.push(...res.result.list);
			if (res.result.nextToken) {
				await doit(res.result.nextToken);
			}
		};
		await doit(null);
		return resList;
	}

	/**
	 *
	 * 发起一个审批实例
	 *
	 * @param {string} processCode 审批流模板code
	 * @param {dingTalk.nv.request.IStartProcessInstance} params 发起参数
	 * @return {*}
	 * @memberof PlatformDingTalkBaseOAService
	 */
	async startProcessInstances(processCode: string, params: Dingtalk.nv.request.IStartProcessInstance) {
		params.processCode = processCode;
		const url = `/v1.0/workflow/processInstances`;
		const res = await this.nvRequest<{ instanceId: string }>(url, {
			method: "POST",
			data: {
				...params,
			},
		});
		return res;
	}

	/** 获取一个流程表单的schema */
	async getSchema(processCode: string) {
		const url = `/v1.0/workflow/forms/schemas/processCodes?processCode=${processCode}`;
		const res = await this.nvRequest<Dingtalk.nv.response.IGetSchema>(url, { method: "GET" });
		return res;
	}

	/** 获取一个用户的待处理审批任务数量 */
	async getOneUserTodotasks(userId: string) {
		const url = `/v1.0/workflow/processes/todoTasks/numbers?userId=${userId}`;
		const res = await this.nvRequest<{ result: number }>(url, { method: "GET" });
		return res;
	}
}
